#include "YaRRIncludes.h"


/************************************** Polite Request ***************************************
** I have put a lot of time and effort into YaRR. If you want to use some of the source     **
** please tell me. Anything used from YaRR must be open source, as is scripts.dll.          **
***************************************** Thank you *****************************************/


unsigned char YaRRFunctions::Backup[Backuplen];
unsigned char YaRRFunctions::NoGameoverBackup[5];
unsigned char YaRRFunctions::Pausetmp[6];
char YaRRFunctions::BuildingDISounds[11][2][31] = {
	{"m00bnpp_hlth0001i1evan_snd.wav", "m00bgpp_hlth0001i1evag_snd.wav"},
	{"m00bnhn_hlth0001i1evan_snd.wav", "m00bgib_hlth0001i1evag_snd.wav"},
	{"m00bnaf_hlth0001i1evan_snd.wav", "m00bgwf_hlth0001i1evag_snd.wav"},
	{"m00bntr_hlth0001i1evan_snd.wav", "m00bgtr_hlth0001i1evag_snd.wav"},
	{"m00bncc_hlth0001i1evan_snd.wav", "m00bgcc_hlth0001i1evag_snd.wav"},
	{"m00bnrf_hlth0001i1evan_snd.wav", "m00bgrf_hlth0001i1evag_snd.wav"},
	{"                              ", "                              "},
	{"m00bnhp_hlth0001i1evan_snd.wav", "m00bghp_hlth0001i1evag_snd.wav"},
	{"m00bncy_hlth0001i1evan_snd.wav", "m00bgcy_hlth0001i1evag_snd.wav"},
	{"m00bnol_hlth0001i1evan_snd.wav", "m00bgat_hlth0001i1evag_snd.wav"}};




void YaRRFunctions::Startup()
{
	DLOG;
	ReadMemory(0x0045730C, (void *)Backup, Backuplen);
}

void YaRRFunctions::Shutdown()
{
	DLOG;
	WriteMemory(0x0045730C, (void *)Backup, Backuplen);
}


void YaRRFunctions::YaRRError(const char *Error)
{
	DLOG;
	if(YaRRGlobal::IRC != 0)
	{
		IRC::SendC('b', "\x03%.2d[FATAL ERROR]: %s", 4, Error);
	}
	MessageBoxA(NULL, Error, "Error!", MB_OK);
	ExitProcess(0);
}

void YaRRFunctions::ListFiles(Stacker<char *> *stack, const char *Path)
{
	DLOG;
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind = INVALID_HANDLE_VALUE;

	hFind = FindFirstFile(Path, &FindFileData);
	if(FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
	{
		stack->Push(strdup2(FindFileData.cFileName));
	}
	while (FindNextFile(hFind, &FindFileData) != 0) 
	{
		if(FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
		{
			stack->Push(strdup2(FindFileData.cFileName));
		}
	}
	FindClose(hFind);
}

void YaRRFunctions::DeleteList(void *stack)
{
	DLOG;
	Stacker<void *> *s = (Stacker<void *> *)stack;

	void *it;
	s->Reset();
	while(s->Iterate(&it))
	{
		CDealloc(it);
	}

	s->Clear();
}
#ifdef _YaRRDebug
char *YaRRFunctions::strdup3(const char *string, int Line, const char *File)
{
	DLOG;
	char *ret = (char *)CAlloc(strlen(string)+1);
	strcpy(ret, string);
	printf("strdup3: 0x%p : %d : %s : \"%s\"\n", ret, Line, File, string);
	return ret;
}
#else
char *YaRRFunctions::strdup2(const char *string)
{
	DLOG;
	char *ret = (char *)CAlloc(strlen(string)+1);
	strcpy(ret, string);
	return ret;
}
#endif


void YaRRFunctions::Explode(const char *String, char Delimiter, Stacker<char *> *Array)
{
	DLOG;
	if(!String)
	{
		return;
	}
	char buf[1024];
	int y = 0;
	for(unsigned int i = 0; i <= strlen(String); i++)
	{
		buf[y] = String[i];
		if(buf[y] == Delimiter)
		{
			buf[y] = '\0';
			Array->Push(strdup2(buf));
			y = 0;
			continue;
		}
		else if(buf[y] == '\0')
		{
			if(y > 0)
			{
				Array->Push(strdup2(buf));
			}
			break;
		}
		y++;
	}
}


const char *YaRRFunctions::Implode(Stacker<char *> *Tokens, int Offset)
{
	DLOG;
	char *s = 0;
	char *tmp = 0;
	Tokens->Reset();
	int i = 0;

	while(Tokens->Iterate(&tmp))
	{
		if(i >= Offset)
		{
			if(!s)
			{
				s = (char *)CAlloc(strlen(tmp)+1);
				strcpy(s, tmp);
			}	
			else
			{
				s = (char *)RAlloc(s, strlen(tmp)+2+strlen(s));
				strcat(s, " ");
				strcat(s, tmp);
			}
		}
		i++;
	}
	return s;
}


void YaRRFunctions::ConsoleInputF(const char *Format, ...)
{
	DLOG;
	char buffer[256];
	va_list va;
	_crt_va_start(va, Format);
	vsnprintf(buffer, 256, Format, va);
	va_end(va);

	char *buf = strdup2(buffer);
	IterateStack(g, Global, YaRRGlobal::Globals)
	{
		int off = 0;
		if(strcmp(g.Name, "MostKills") == 0)
		{
			off = 4;
		}
		if(strcmp(g.Name, "MostDeaths") == 0)
		{
			off = 4;
		}
		if(strcmp(g.Name, "VehiclesDestroyed") == 0)
		{
			off = 4;
		}
		if(strcmp(g.Name, "MVP") == 0)
		{
			off = 4;
		}
		char name[256];
		sprintf(name, ":%s:", g.Name);
		Replace(buf, name, (char *)g.Data+off);
	}
	
	Console_Input(buf);
	CDealloc(buf);
}

bool YaRRFunctions::IsNickBanned(const char *Nick)
{
	DLOG;
	Stacker<YaRRDatabase::Row *> result;
	YaRRDatabase::Query(&result, "SELECT * FROM Bans WHERE Nick = '%q';", Nick);
	bool ret = (result.Length() > 0);
	YaRRDatabase::DeleteResult(&result);
	return ret;
}

bool YaRRFunctions::IsIPBanned(const char *IP)
{
	DLOG;
	Stacker<YaRRDatabase::Row *> result;
	YaRRDatabase::Query(&result, "SELECT * FROM Bans WHERE IP = '%q';", IP);
	bool ret = (result.Length() > 0);
	YaRRDatabase::DeleteResult(&result);
	return ret;
}

bool YaRRFunctions::GetBanInfo(YaRRFunctions::BanInfo *ifo, const char *Nick, const char *IP)
{
	DLOG;
	Stacker<YaRRDatabase::Row *> result;
	YaRRDatabase::Query(&result, "SELECT * FROM Bans WHERE Nick = '%q' OR IP = '%q';", Nick, IP);

	if(result.Length() == 0)
	{
		YaRRDatabase::DeleteResult(&result);
		return 0;
	}

	strcpy(ifo->Nick, YaRRDatabase::GetColumnData("Nick", result[0]->Columns));
	strcpy(ifo->Banner, YaRRDatabase::GetColumnData("WhoBy", result[0]->Columns));
	strcpy(ifo->Reason, YaRRDatabase::GetColumnData("Reason", result[0]->Columns));
	ifo->Time = atoi(YaRRDatabase::GetColumnData("Time", result[0]->Columns));
	YaRRDatabase::DeleteResult(&result);
	return 1;
}

void YaRRFunctions::BootPlayer(int ID, const char *reason, ...)
{
	DLOG;
	char buffer[256];
	va_list va;
	_crt_va_start(va, reason);
	vsnprintf(buffer, 256, reason, va);
	va_end(va);

	char buf[270];
	sprintf(buf, "%d,%s", ID, buffer);

	Attach_Script_Once(Commands->Create_Object("invisible_object", Vector3(0.0,0.0,0.0)), "YaRRBoot", buf);
}

int YaRRFunctions::FindPlayer(const char *Part)
{
	DLOG;
	int Player = -1;
	for(GenericSLNode *x = PlayerList->HeadNode; x != 0; x = x->NodeNext)
	{
		cPlayer *p = (cPlayer *)x->NodeData;
		if(p && p->IsActive)
		{
			const char *pName = WideCharToChar(p->PlayerName);
			if(stricmp(pName, Part) == 0)
			{
				delete []pName;
				Player = p->PlayerId;
				break;
			}
			if(stristr(pName, Part))
			{
				if(Player >= 0)
				{
					delete []pName;
					return -2;
				}
				else
				{
					Player = p->PlayerId;
				}
			}
			delete []pName;
		}
	}
	return Player;	
}

const char *YaRRFunctions::GetWeaponString(GameObject *obj, char *Buffer, int Size)
{
	DLOG;
	if(As_SoldierGameObj(obj) == 0)
	{
		Buffer[0] = '\0';
		return Buffer;
	}
	if(Get_Vehicle(obj) == 0)
	{
		sprintf_s(Buffer, Size, "%S/%S", Get_Wide_Translated_Preset_Name(obj), Get_Current_Wide_Translated_Weapon(obj));
	}
	else
	{
		sprintf_s(Buffer, Size, "%s", Get_Translated_Preset_Name(Get_Vehicle(obj)));
	}
	return Buffer;
}

char *YaRRFunctions::RemovePunct(char *str) 
{
	DLOG;
	int x = 0; 
	for(int i = 0;;i++) 
	{
		if(!ispunct(str[i]))
		{ 
			str[x++] = str[i];
		} 
		if(str[i] == '\0') 
		{
			str[x] = '\0'; 
		} 
	} 
	return str;  
}

char *YaRRFunctions::RemoveWhite(char *str) 
{
	DLOG;
	int x = 0; 
	for(int i = 0;;i++) 
	{
		if(!isspace(str[i]))
		{ 
			str[x++] = str[i];
		} 
		if(str[i] == '\0') 
		{
			str[x] = '\0'; 
		} 
	} 
	return str;  
}

char *YaRRFunctions::ToLower(char *str)
{
	DLOG;
	char *x = str;
	for(; *str != 0; str++) 
	{
		*str = (char)tolower(*str);
	}
	return x;
}

int YaRRFunctions::GetStatus(char access)
{
	DLOG;
	if(access == '+')
	{
		return 1;
	}
	else if(access == '%')
	{
		return 2;
	}
	else if(access == '@')
	{
		return 3;
	}
	else if(access == '&')
	{
		return 4;
	}
	else if(access == '~')
	{
		return 5;
	}
	return 0;
}

void YaRRFunctions::GetStatusName(char Access, char *buffer)
{
	DLOG;
	if(Access == '+')
	{
		strcpy(buffer, "temp moderator");
	}
	else if(Access == '%')
	{
		strcpy(buffer, "half moderator");
	}
	else if(Access == '@')
	{
		strcpy(buffer, "full moderator");
	}
	else if(Access == '&')
	{
		strcpy(buffer, "administrator");
	}
	else if(Access == '~')
	{
		strcpy(buffer, "founder");
	}
	else
	{
		strcpy(buffer, "normal player");
	}
}

void YaRRFunctions::FormatTime(time_t t, char *buffer, int Length)
{
	DLOG;
	strftime(buffer, Length, "%d/%m/%Y %H:%M:%S", localtime(&t));
}

void YaRRFunctions::FormatTime(time_t t, const char *Format, char *buffer, int Length)
{
	DLOG;
	//http://www.cplusplus.com/reference/clibrary/ctime/strftime.html
	strftime(buffer, Length, Format, localtime(&t));
}

const char *YaRRFunctions::GetPlayerName(int ID)
{
	DLOG;
	if(Players == 0)
	{
		YaRRPlayers::Startup();
		return 0;
	}
	if(Players[ID] == 0)
	{
		return 0;
	}

	return Players[ID]->Nick;
}

void YaRRFunctions::PPage(int ID, const char *Format, ...)
{
	DLOG;
	if(ID < 1)
	{
		return;
	}
	char buffer[256];
	va_list va;
	_crt_va_start(va, Format);
	vsnprintf(buffer, 256, Format, va);
	va_end(va);

	Player *p = YaRRPlayers::Find(ID);
	if(!p)
	{
		ConsoleInputF("ppage %d %s", ID, buffer);
		return;
	}
	if(p->BHS < 2.9)
	{
		ConsoleInputF("ppage %d %s", ID, buffer);
		return;
	}
	else
	{
		ConsoleInputF("cmsgp %d %d,%d,%d %s", ID, p->PPageColour.R, p->PPageColour.G, p->PPageColour.B, buffer);
		if(stricmp(p->PPageSound, "none") != 0)
		{
			ConsoleInputF("sndp %d %s", ID, p->PPageSound);
		}
		return;
	}
}

void YaRRFunctions::PPageErr(int ID, const char *Format, ...)
{
	DLOG;
	char buffer[256];
	va_list va;
	_crt_va_start(va, Format);
	vsnprintf(buffer, 256, Format, va);
	va_end(va);

	Player *p = YaRRPlayers::Find(ID);
	if(!p)
	{
		ConsoleInputF("ppage %d %s", ID, buffer);
		return;
	}
	if(p->BHS < 2.9)
	{
		ConsoleInputF("ppage %d %s", ID, buffer);
		return;
	}
	else
	{
		Colour::CRGB colour = YaRRSettings::MessageColourError;
		ConsoleInputF("cmsgp %d %d,%d,%d %s", ID, colour.R, colour.G, colour.B, buffer);
		return;
	}
}

const char *YaRRFunctions::GetPresetScreenName(GameObject *obj)
{
	DLOG;
	const char *temp = WideCharToChar(Get_Wide_Translated_Preset_Name(obj));
	const char *ret = strdup2(temp);
	delete []temp;
	if(strcmp(ret, "No String") == 0)
	{
		char tmp[256];
		Settings->INI->Get_String("Translated_Preset", Commands->Get_Preset_Name(obj), "ERR", tmp, 256);
		if(strcmp(tmp, "ERR") == 0)
		{
			CDealloc(ret);
			return 0;
		}
		else
		{
			CDealloc(ret);
			ret = strdup2(tmp);
		}
	}
	return ret;
}

const char *YaRRFunctions::GetPresetScreenName(const char *preset)
{
	DLOG;
	const wchar_t *wcs = Get_Wide_Translated_Preset_Name_By_Preset(preset);
	if(!wcs)
	{
		return strdup2(preset);
	}
	const char *tmp = WideCharToChar(wcs);
	const char *ret = strdup2(tmp);
	delete []tmp;
	if(strcmp(ret, "No String") == 0)
	{
		char tmp[256];
		Settings->INI->Get_String("Translated_Preset", preset, "ERR", tmp, 256);
		if(strcmp(tmp, "ERR") == 0)
		{
			CDealloc(ret);
			return 0;
		}
		else
		{
			CDealloc(ret);
			ret = strdup2(tmp);
		}
	}
	return ret;
}
unsigned char tempback[4];


void YaRRFunctions::ApplyNoPendingPatch()
{
	DLOG;
	ReadMemory(0x0472c95, (void *)tempback, 4);

	unsigned char tmp[4] = {0x90, 0xBA, 0x01, 0x00};
	if(!WriteMemory(0x0472c95, tmp, 4))
	{
		printf("[YaRR] No gameplay pending patch couldn't be applied.\n");
		return;
	}

	unsigned char tmp2 = 0xEB;
	if(!WriteMemory(0x0478A93, &tmp2, 1))
	{
		printf("[YaRR] No gameplay pending patch couldn't be applied.\n");
		return;
	}

	printf("[YaRR] No gameplay pending patch was successfuly applied.\n");
}

void YaRRFunctions::ApplyStartButtonFix()
{
	DLOG;
	char op = '\xE9';
	int set = (int)StartButton_Glue - 0x004C0F40 - 5;
	
	WriteMemory(0x004C0F40, &op, 1);
	WriteMemory(0x004C0F41, &set, 4);	
}


bool YaRRFunctions::Vowel(char _c)
{
	DLOG;
	return strchr("aeiou", tolower(_c)) == 0 ? false : true;
}

bool YaRRFunctions::IsNumber(const char *_str)
{
	for(;*_str != 0; _str++)
	{
		if(!isdigit(*_str))
		{
			return 0;
		}
	}
	return 1;
}

bool YaRRFunctions::sortalpha(char a, char b)
{
	DLOG;
	char abc[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
	char num[] = {'0','1','2','3','4','5','6','7','8','9'};

	if(!isalnum(a) && !isalnum(b))
	{
		return 0;
	}

	if(isdigit(b) && !isdigit(a))
	{
		return 1;
	}

	if(isdigit(a) && !isdigit(b))
	{
		return 0;
	}

	for(int i = 0; i < 26; i++)
	{
		if(a == abc[i])
		{
			a = (char)i+10;
			break;
		}
	}

	for(int i = 0; i < 26; i++)
	{
		if(b == abc[i])
		{
			b = (char)i+10;
			break;
		}
	}

	for(int i = 0; i < 10; i++)
	{
		if(a == num[i])
		{
			a = (char)i;
			break;
		}
	}

	for(int i = 0; i < 10; i++)
	{
		if(b == num[i])
		{
			b = (char)i;
			break;
		}
	}

	return a > b;
}


void YaRRFunctions::Sort(Stacker<char> &stack, bool (*comparitor)(char a, char b))
{
	DLOG;
	char *arr = (char *)CAlloc(stack.Length());

	int tmp = 0;
	IterateStack(x, char, (&stack))
	{
		arr[tmp++] = x;
	}
	int len = stack.Length();

	bool nochange = 1;
	while(nochange)
	{
		nochange = 0;
		for(int i = 0; i < len-1; i++)
		{
			
			int y = i + 1;
			if(comparitor(arr[i], arr[y]))
			{
				char c = arr[i];
				arr[i] = arr[y];
				arr[y] = c;
				nochange = 1;
			}
		}
	}

	CDealloc(arr);
}

void YaRRFunctions::Sort(Stacker<char *> &stack, bool (*comparitor)(char a, char b), int offset)
{
	DLOG;
	struct word
	{
		char *_word;
	};

	word *arr = (word *)CAlloc(stack.Length()*sizeof(word));

	int t = 0;
	IterateStack(x, char *, (&stack))
	{
		arr[t++]._word = x;
	}
	
	int len = stack.Length();
	bool nochange = 1;
	while(nochange)
	{
		nochange = 0;
		for(int i = 0; i < len-1; i++)
		{
			
			int y = i + 1;
			if(comparitor(*(arr[i]._word+offset), *(arr[y]._word+offset)))
			{
				char *c = arr[i]._word;
				arr[i]._word = arr[y]._word;
				arr[y]._word = c;
				nochange = 1;
			}
		}
	}
	
	stack.Clear();
	for(int i = 0; i < len; i++)
	{
		stack.Push(arr[i]._word);
	}

	CDealloc(arr);
}

bool YaRRFunctions::HexToRGB(Colour::CRGB *rgb, const char *Hex)
{
	DLOG;
	unsigned long colour;
	if(!sscanf(Hex, "%lx", &colour))
	{
		return 0;
	}
	rgb->R = (colour & 0xFF0000) >> 16;
	rgb->G = (colour & 0xFF00) >> 8;
	rgb->B = colour & 0xFF;
	return 1;
}

char *YaRRFunctions::Replace(char *Str, const char *At, const char *With)
{
	DLOG;
	if(strlen(At) > strlen(Str))
	{
		return Str;
	}
	while(strstr(Str, At) != 0)
	{
		char *x = strstr(Str, At);
		char *tmp = (char *)CAlloc(strlen(Str)+strlen(With)-strlen(At)+1);
		
		Str[strlen(Str)-strlen(x)] = 0;
		strcpy(tmp, Str);
		strcat(tmp, With);
		strcat(tmp, Str+strlen(Str)-strlen(x)+strlen(At));
		Str = (char *)RAlloc((void *)Str, strlen(tmp)+1);
#ifdef _YaRRDebug
		printf("[replace]: allocated %d blocks for \"%s\"\n", strlen(tmp)+1, tmp);
#endif
		memcpy((char *)Str, (char *)tmp, strlen(tmp)+1);
		CDealloc(tmp);
	}
	return Str;
}

void YaRRFunctions::Pause()
{
	DLOG;
	YaRRHooking::RunGame = 0;
	unsigned char tmp[6] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
	ReadMemory(0x0472c95, Pausetmp, 6);
	WriteMemory(0x0472c95, tmp, 6);

	char op = '\xE9';
	int set = (int)NoGameover_Glue - 0x4616A0  - 5;
	ReadMemory(0x4616A0, NoGameoverBackup, 5);
	WriteMemory(0x4616A0 , &op, 1);
	WriteMemory(0x4616A0+1, &set, 4);
}

void YaRRFunctions::Resume()
{
	DLOG;
	YaRRHooking::RunGame = 1;
	WriteMemory(0x0472c95, Pausetmp, 6);
	WriteMemory(0x4616A0, NoGameoverBackup, 5);
}	

int YaRRFunctions::GetPCount(int team)
{
	DLOG;
	int count = 0;
	for(GenericSLNode *x = PlayerList->HeadNode; x != 0; x = x->NodeNext)
	{
		cPlayer *p = (cPlayer *)x->NodeData;
		if(p->IsInGame && (Get_Team(p->PlayerId) == 2 || Get_Team(p->PlayerId) == team))
		{
			count++;
		}
	}
	return count;
}

void YaRRFunctions::RGBToHex(Colour::CRGB &rgb, char *buffer)
{
	DLOG;
	sprintf(buffer, "%x%x%x", rgb.R, rgb.G, rgb.B);
}

void YaRRFunctions::CheckNodeBan(Player *p)
{
	Stacker<YaRRDatabase::Row *> Result;
	YaRRDatabase::Query(&Result, "SELECT * FROM NodeBans WHERE Nick = '%q' OR Node = '%q';", p->Nick, p->Node);
	if(!Result.Empty())
	{
		const char *banner = YaRRDatabase::GetColumnData("Banner", Result[0]->Columns);
		const char *date = YaRRDatabase::GetColumnData("Date", Result[0]->Columns);
		const char *Reason = YaRRDatabase::GetColumnData("Reason", Result[0]->Columns);
		BootPlayer(p->ID, "You were banned on %s for \"%s\" by %s.", date, Reason, banner);
		ConsoleInputF("msg %s was kicked from the game (banned)", p->Nick);
		YaRRDatabase::DeleteResult(&Result);
	}
}

unsigned int YaRRFunctions::GetWorth(const char *Preset)
{
	DLOG;
	IterateStack(x, ObjectWorth, YaRRSettings::ObjectWorthList)
	{
		if(strcmp(x.Preset, Preset) == 0)
		{
			return x.Worth;
		}
	}
	int c = Get_Cost(Preset);
	return c == 0 ? 1 : c;
}

const char *YaRRFunctions::FindDISound(GameObject *obj)
{
	DLOG;
	int bld = Building_Type(obj);
	if(bld == -1)
	{
		return "";
	}
	int type = Get_Object_Type(obj);
	if(type < 0 || type > 1)
	{
		return "";
	}
	return BuildingDISounds[bld][type];
}

int YaRRFunctions::GetTeamPlayerCount(int team)
{
	int Total = 0;
	GenericSLNode *x = PlayerList->HeadNode;
	while (x)
	{
		cPlayer *p = (cPlayer *)x->NodeData;
		if(p->IsInGame && p->IsActive)
		{
			Total++;
		}
		x = x->NodeNext;
	}
	return Total;
}

int YaRRFunctions::GetTeamColour(int team)
{
	if(team == 0)
	{
		return 4;
	}
	if(team == 1)
	{
		return 8;
	}
	return 0;
}

void YaRRFunctions::PlaySound(void *Sound, int Type, int Where, int Target)
{
	if(Type == 0)
	{
		if(Where == 0)
		{
			ConsoleInputF("snda %s", Sound);
		}
		else if(Where == 1)
		{
			ConsoleInputF("sndp %d %s", Target, Sound);
		}
	}
	else
	{
		char tmp[128];
		sprintf(tmp, "%d,%d", Sound, Target);
		Attach_Script_Once(Get_GameObj(1), "YaRR_PlaySound", tmp);
	}
}

void YaRRFunctions::Send_Message(int ID, WideStringClass &Message, int _Type, int Host, int Target)
{
	DLOG;
	__asm
	{
		mov eax, 6C8h;
		push eax;

		mov eax, 0x672410;
		call eax;

		mov ecx, eax;
		push ecx;

		mov eax, 0x4B9140;
		call eax;

		pop ecx;

		mov eax, Target;
		push eax;

		mov eax, ID;
		push eax;

		mov eax, Host;
		push eax;
		
		mov eax, _Type;
		push eax;

		mov eax, Message;
		push eax;

		mov eax, 0x4B91F0;
		call eax;
	}
}

void YaRRFunctions::SendMessageF(int ID, int Type, int Host, int Target, const char *Format, ...)
{
	DLOG;
	char buffer[256];
	va_list va;
	_crt_va_start(va, Format);
	vsnprintf(buffer, 256, Format, va);
	va_end(va);

	WideStringClass Msg;
	if(Msg.Convert_From(buffer))
	{
		YaRRFunctions::Send_Message(ID, Msg, Type, Host, Target);
	}
}

void YaRRFunctions::Send_SCAnnouncement(int ID, int a , int b, int Message, int c)
{
	DLOG;
	/*__asm
	{
		mov eax, 6C8h;
		push eax;

		mov eax, 0x672410;
		call eax;

		mov ecx, eax;
		push ecx;

		mov eax, 0x61E120;
		call eax;

		pop ecx;

		mov eax, Target;
		push eax;

		mov eax, ID;
		push eax;

		mov eax, Host;
		push eax;
		
		mov eax, _Type;
		push eax;

		mov eax, Message;
		push eax;

		mov eax, 0x4B3930;
		call eax;
	}*/
}